package com.yonyou.brigade.third_parties.hcholiday.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yonyou.brigade.basic_init.enums.ChannelEnum;
import com.yonyou.brigade.basic_init.model.BriChannel;
import com.yonyou.brigade.basic_init.model.IChannelConfig;
import com.yonyou.brigade.basic_init.service.IBriChannelService;
import com.yonyou.brigade.basic_init.service.IUserCenterService;
import com.yonyou.brigade.order_center.model.ThirdResult;
import com.yonyou.brigade.third_parties.common.model.ThirdUser;
import com.yonyou.brigade.third_parties.hcholiday.constant.HcHolidayConstant;
import com.yonyou.brigade.third_parties.hcholiday.dao.HcHolidayUserMapper;
import com.yonyou.brigade.third_parties.hcholiday.model.HcHolidayConfig;
import com.yonyou.brigade.third_parties.hcholiday.model.HcHolidayUser;
import com.yonyou.brigade.third_parties.hcholiday.model.third.CertificateInfo;
import com.yonyou.brigade.third_parties.hcholiday.model.third.HcHolidayParamHead;
import com.yonyou.brigade.third_parties.hcholiday.model.third.HcHolidayRequestParam;
import com.yonyou.brigade.third_parties.hcholiday.model.third.HcHolidayUserDTO;
import com.yonyou.brigade.third_parties.hcholiday.service.IHcHolidayPublicService;
import com.yonyou.brigade.third_parties.hcholiday.service.IHcHolidayUserService;
import com.yonyou.brigade.third_parties.hcholiday.util.HcHolidaySignUtil;
import com.yonyou.brigade.third_parties.hcholiday.util.HcHolidayUserUtil;
import com.yonyou.brigade.util.operateutil.CompareUtils;
import com.yonyou.ybzboot.starter.common.exception.CustomException;
import com.yonyou.ybzboot.uc.dto.UcUserDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * 花城用户 服务实现类
 *
 * @author kangfw5
 * @date 2019-06-18
 */
@Service
@Slf4j
public class HcHolidayUserServiceImpl extends ServiceImpl<HcHolidayUserMapper, HcHolidayUser> implements IHcHolidayUserService {
    private final String COMPARE_PROPERTIES = "wname,rank,mobile,email";

    @Value("${hcholiday.url}")
    private String hcHolidayUrl;
    @Value("${brigade.url.noaccess}")
    private String BRIGADE_NOACCESS_URL;

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private IHcHolidayPublicService hcHolidayPublicService;
    @Autowired
    private IBriChannelService briChannelService;
    @Autowired
    private IUserCenterService userCenterService;

    @Override
    public String getLoginUrl(String tenant, String org, String phone, String pageType, String pcOrH5, String jsonExt) {
        //未查到开通配置信息则返回未开通页面URL
        BriChannel briChannel = briChannelService.getEnableInfoByTenantOrg(tenant, org, ChannelEnum.HCHOLIDAY.getName());
        HcHolidayConfig hcHolidayConfig = (HcHolidayConfig) briChannelService.getChannelConfig(tenant, ChannelEnum.HCHOLIDAY.getName(), org, new HcHolidayConfig());
        if (hcHolidayConfig == null) {
            return BRIGADE_NOACCESS_URL;
        }
        //查询用户中心用户数据，为初次同步用户以及信息比对做准备
        UcUserDto ucUserDto = userCenterService.getCompleteUcUserDtoByPhone(phone, tenant);
        if (ucUserDto == null) {
            throw new CustomException("用户信息不存在或未进入用户中心");
        }
        HcHolidayUser hcHolidayUserFromUserCenter = HcHolidayUserUtil.ucUser2Hc(tenant, hcHolidayConfig.getCuicode(), ucUserDto);
        if (BriChannel.SYNCUSER == briChannel.getSyncUser()) {
            //查询本地同步用户记录
            Wrapper<HcHolidayUser> hcUserWrapper = new EntityWrapper<>();
            hcUserWrapper.eq(HcHolidayUser.MOBILE, phone).eq(HcHolidayUser.TENANT, tenant);
            List<HcHolidayUser> hcHolidayUserList = this.selectList(hcUserWrapper);
            //如果未同步则首次同步
            if (CollectionUtils.isEmpty(hcHolidayUserList)) {
                this.addUser(hcHolidayConfig, hcHolidayUserFromUserCenter);
            } else {
                //比较用户信息是否变更，更新第三方数据
                Map<String, String> compareMap = new HashMap<>();
                String[] compareFileds = COMPARE_PROPERTIES.split(",");
                for (String compareFiled : compareFileds) {
                    compareMap.put(compareFiled, "");
                }
                Map<String, Object> compareResult = CompareUtils.getModifyContent(hcHolidayUserList.get(0), hcHolidayUserFromUserCenter, compareMap);
                if (compareResult != null && compareResult.size() > 0) {
                    this.updateUser(hcHolidayConfig, hcHolidayUserFromUserCenter);
                }
            }
        }
        //生产地址： https://hctmc.hcholiday.com/mfs/ui/sso-open/index.html
        String loginClass = "HC-MFS.MFSSsoLoginImpl";
        String wcodeSrc = hcHolidayUserFromUserCenter.getWcodeSrc();
        String publishname = "mfs";
        String cuicode = hcHolidayConfig.getCuicode();
        String sign = DigestUtils.md5DigestAsHex((wcodeSrc + cuicode + "001").getBytes()).toUpperCase();
        return hcHolidayUrl + HcHolidayConstant.METHOD_HTML_LOGIN + "?_SSO.LoginAuth=" + loginClass + "&username=" + wcodeSrc + "&publishname=" + publishname + "&cuicode=" + cuicode + "&sign=" + sign;
    }

    /**
     * 花城最初提供的批量接口只能全部成功或全部失败！
     *
     * @param channelConfig 配置信息
     * @param userList      用户列表
     * @return
     */
    @Override
    public ThirdResult syncUsers(IChannelConfig channelConfig, List<ThirdUser> userList) {
        List<String> msg = new ArrayList<>();

        for (ThirdUser thirdUser : userList) {
            try {
                ThirdResult oneResult = this.addUser(channelConfig, thirdUser);
                msg.add(oneResult.getMsg());
            } catch (Exception e) {
                log.info("用户同步异常{}", JSON.toJSONString(thirdUser), e);
                msg.add(e.getMessage());
            }
        }
        return new ThirdResult(true, "同步完成", msg);
    }

    @Override
    public ThirdResult addUser(IChannelConfig channelConfig, ThirdUser thirdUser) {

        HcHolidayConfig config = (HcHolidayConfig) channelConfig;
        HcHolidayParamHead head = new HcHolidayParamHead(hcHolidayPublicService.getToken(config), null, HcHolidayConstant.HC_INTERFACE_VERSION);
        HcHolidayRequestParam param = new HcHolidayRequestParam();
        param.setHead(head);

        String url = hcHolidayUrl + HcHolidayConstant.METHOD_POST_ACCESS.replace("{sender}", config.getSender()).replace("{interfaceId}", HcHolidayConstant.INTERFACE_ADD_WCODES);
        param.setData(Collections.singletonList(convertUser((HcHolidayUser) thirdUser)));
        String sign = HcHolidaySignUtil.generateSign(param, config);
        param.getHead().setSign(sign);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(param), headers);
        String result = restTemplate.postForObject(url, entity, String.class);

        ThirdResult thirdResult = handleResult(result);
        if (thirdResult.getSuccess()) {
            this.insert((HcHolidayUser) thirdUser);
        }
        return thirdResult;
    }

    @Override
    public ThirdResult updateUser(IChannelConfig channelConfig, ThirdUser thirdUser) {
        HcHolidayUser hcHolidayUser = (HcHolidayUser) thirdUser;
        HcHolidayConfig config = (HcHolidayConfig) channelConfig;
        String token = hcHolidayPublicService.getToken(config);
        HcHolidayParamHead head = new HcHolidayParamHead(token, null, HcHolidayConstant.HC_INTERFACE_VERSION);
        HcHolidayRequestParam param = new HcHolidayRequestParam();
        param.setHead(head);
        HcHolidayUserDTO userDTO = convertUser4update(hcHolidayUser);
        param.setData(userDTO);
        String sign = HcHolidaySignUtil.generateSign(param, config);
        param.getHead().setSign(sign);

        String url = hcHolidayUrl + HcHolidayConstant.METHOD_POST_ACCESS.replace("{sender}", config.getSender()).replace("{interfaceId}", HcHolidayConstant.INTERFACE_UPDATE_WCODE);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(param), headers);
        String result = restTemplate.postForObject(url, entity, String.class);

        ThirdResult thirdResult = handleResult(result);
        if (thirdResult.getSuccess()) {
            Wrapper<HcHolidayUser> wrapper = new EntityWrapper<>();
            wrapper.eq(HcHolidayUser.TENANT, hcHolidayUser.getTenant()).eq(HcHolidayUser.MOBILE, hcHolidayUser.getMobile());
            this.update(hcHolidayUser, wrapper);
        }
        return thirdResult;
    }

    private ThirdResult handleResult(String result) {
        JSONObject jsonResult = JSON.parseObject(result);
        if ("success".equals(jsonResult.getString("status"))) {
            return new ThirdResult(true, null, jsonResult.getString("data"));
        } else {
            return new ThirdResult(false, jsonResult.getString("message"));
        }
    }


    private HcHolidayUserDTO convertUser(HcHolidayUser hcHolidayUser) {
        HcHolidayUserDTO userDTO = new HcHolidayUserDTO();
        BeanUtils.copyProperties(hcHolidayUser, userDTO);
        CertificateInfo cardInfo = new CertificateInfo();
        if (!StringUtils.isEmpty(hcHolidayUser.getCardnum())) {
            cardInfo.setCardnum(hcHolidayUser.getCardnum());
            cardInfo.setCardtype(hcHolidayUser.getCardtype());
        } else {
            throw new CustomException("用户缺少证件信息");
        }
        userDTO.setCardInfos(Collections.singletonList(cardInfo));
        hcHolidayUser.setCardnum(null);
        hcHolidayUser.setCardtype(null);
        return userDTO;
    }

    private HcHolidayUserDTO convertUser4update(HcHolidayUser hcHolidayUser) {
        HcHolidayUserDTO userDTO = new HcHolidayUserDTO();
        userDTO.setCuicode(hcHolidayUser.getCuicode());
        userDTO.setWcodeSrc(hcHolidayUser.getWcodeSrc());
        userDTO.setStatus(hcHolidayUser.getStatus());
        userDTO.setRank(hcHolidayUser.getRank());
        userDTO.setMobile(hcHolidayUser.getMobile());
        userDTO.setSex(hcHolidayUser.getSex());
        userDTO.setEmail(hcHolidayUser.getEmail());

        userDTO.setQq("");
        userDTO.setWeixin("");
        userDTO.setShortcode("");

        return userDTO;
    }
}
